home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / APIHELPTOPIC.PY < prev    next >
Encoding:
Python Source  |  2000-06-15  |  9.3 KB  |  276 lines

  1. ##############################################################################
  2. # Zope Public License (ZPL) Version 1.0
  3. # -------------------------------------
  4. # Copyright (c) Digital Creations.  All rights reserved.
  5. # This license has been certified as Open Source(tm).
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions are
  8. # met:
  9. # 1. Redistributions in source code must retain the above copyright
  10. #    notice, this list of conditions, and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. #    notice, this list of conditions, and the following disclaimer in
  13. #    the documentation and/or other materials provided with the
  14. #    distribution.
  15. # 3. Digital Creations requests that attribution be given to Zope
  16. #    in any manner possible. Zope includes a "Powered by Zope"
  17. #    button that is installed by default. While it is not a license
  18. #    violation to remove this button, it is requested that the
  19. #    attribution remain. A significant investment has been put
  20. #    into Zope, and this effort will continue if the Zope community
  21. #    continues to grow. This is one way to assure that growth.
  22. # 4. All advertising materials and documentation mentioning
  23. #    features derived from or use of this software must display
  24. #    the following acknowledgement:
  25. #      "This product includes software developed by Digital Creations
  26. #      for use in the Z Object Publishing Environment
  27. #      (http://www.zope.org/)."
  28. #    In the event that the product being advertised includes an
  29. #    intact Zope distribution (with copyright and license included)
  30. #    then this clause is waived.
  31. # 5. Names associated with Zope or Digital Creations must not be used to
  32. #    endorse or promote products derived from this software without
  33. #    prior written permission from Digital Creations.
  34. # 6. Modified redistributions of any form whatsoever must retain
  35. #    the following acknowledgment:
  36. #      "This product includes software developed by Digital Creations
  37. #      for use in the Z Object Publishing Environment
  38. #      (http://www.zope.org/)."
  39. #    Intact (re-)distributions of any official Zope release do not
  40. #    require an external acknowledgement.
  41. # 7. Modifications are encouraged but must be packaged separately as
  42. #    patches to official Zope releases.  Distributions that do not
  43. #    clearly separate the patches from the original work must be clearly
  44. #    labeled as unofficial distributions.  Modifications which do not
  45. #    carry the name Zope may be packaged in any form, as long as they
  46. #    conform to all of the clauses above.
  47. # Disclaimer
  48. #   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
  49. #   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  50. #   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  51. #   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
  52. #   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  53. #   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  54. #   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  55. #   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  56. #   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  57. #   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  58. #   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  59. #   SUCH DAMAGE.
  60. # This software consists of contributions made by Digital Creations and
  61. # many individuals on behalf of Digital Creations.  Specific
  62. # attributions are listed in the accompanying credits file.
  63. ##############################################################################
  64. """
  65. API documentation help topics
  66. """
  67.  
  68. import types
  69. import string
  70. import HelpTopic
  71. from Globals import HTMLFile, Persistent
  72.  
  73. class APIHelpTopic(HelpTopic.HelpTopic):
  74.     """
  75.     Provides API documentation.
  76.     """
  77.  
  78.     isAPIHelpTopic=1
  79.     
  80.     def __init__(self, id, title, file):
  81.         self.id=id
  82.         self.title=title
  83.         dict={}
  84.         execfile(file, dict)
  85.         self.doc=dict.get('__doc__','')
  86.  
  87.         self.apis=[]
  88.         for v in dict.values():
  89.             if type(v)==types.ClassType:
  90.                 self.apis.append(APIDoc(v))
  91.  
  92.         # try to get title from first non-blank line
  93.         # of module docstring
  94.         if not self.title:
  95.             lines=string.split(self.doc,'\n')
  96.             while 1:
  97.                 line=string.strip(lines[0])
  98.                 if line:
  99.                     self.title=line
  100.                     break
  101.                 lines.pop(0)
  102.                 if not lines:
  103.                     break
  104.         # otherwise get title from first class name
  105.         if not self.title:
  106.             self.title=self.apis[0].name
  107.  
  108.     index_html=HTMLFile('APIHelpView', globals())
  109.  
  110.     def SearchableText(self):
  111.         "The full text of the Help Topic, for indexing purposes"
  112.         text="%s %s" % (self.title, self.doc)
  113.         for api in self.apis:
  114.             text="%s %s %s" % (text, api.SearchableText())
  115.         return text
  116.  
  117.       
  118. class APIDoc(Persistent):
  119.     """
  120.     Describes an API.
  121.     """
  122.  
  123.     extends=()
  124.  
  125.     def __init__(self, klass):
  126.         # Creates an APIDoc instance given a python class.
  127.         # the class describes the API; it contains
  128.         # methods, arguments and doc strings.
  129.         # 
  130.         # The name of the API is deduced from the name
  131.         # of the class.
  132.         #
  133.         # The base APIs are deduced from the __extends__
  134.         # attribute.
  135.         
  136.         self.name=klass.__name__ 
  137.         self.doc=trim_doc_string(klass.__doc__)
  138.  
  139.         # inheritence information
  140.         if hasattr(klass,'__extends__'):
  141.             self.extends=[]
  142.             for base in klass.__extends__:
  143.                 names=string.split(base, '.')
  144.                 url="%s/Help/%s.py#%s" % (names[0], names[1], names[2])
  145.                 self.extends.append((names[2], url))
  146.  
  147.         # constructor information
  148.         if hasattr(klass, '__constructor__'):
  149.             self.constructor=MethodDoc(klass.__constructor__)
  150.         
  151.         # Get info on methods and attributes, ignore special items
  152.         self.attributes=[]
  153.         self.methods=[]
  154.         for k,v in klass.__dict__.items():
  155.             if k not in ('__extends__', '__doc__', '__constructor__'):
  156.                 if type(v)==types.FunctionType:
  157.                     self.methods.append(MethodDoc(v))
  158.                 else:
  159.                     self.attributes.append(AttributeDoc(k, v))
  160.         
  161.     def SearchableText(self):
  162.         """
  163.         The full text of the API, for indexing purposes.
  164.         """
  165.         text="%s %s" % (self.name, self.doc)
  166.         for attribute in self.attributes:
  167.             text="%s %s" % (text, attribute.name)
  168.         for method in self.methods:
  169.             text="%s %s %s" % (text, method.name, method.doc)
  170.         return text
  171.         
  172.     view=HTMLFile('APIView', globals())
  173.     
  174.     
  175. class AttributeDoc(Persistent):
  176.     """
  177.     Describes an attribute of an API.
  178.     """
  179.     
  180.     def __init__(self, name, value):
  181.         self.name=name
  182.         self.value=value
  183.  
  184.     view=HTMLFile('attributeView', globals())
  185.  
  186.  
  187. class MethodDoc(Persistent):
  188.     """
  189.     Describes a method of an API.
  190.     
  191.     required - a sequence of required arguments 
  192.     optional - a sequence of tuples (name, default value)
  193.     varargs - the name of the variable argument or None
  194.     kwargs - the name of the kw argument or None
  195.     """
  196.     
  197.     varargs=None
  198.     kwargs=None
  199.     
  200.     def __init__(self, func):
  201.         if hasattr(func, 'im_func'):
  202.             func=func.im_func
  203.  
  204.         self.name=func.__name__
  205.         self.doc=trim_doc_string(func.__doc__)
  206.         
  207.         # figure out the method arguments
  208.         # mostly stolen from pythondoc
  209.         CO_VARARGS = 4
  210.         CO_VARKEYWORDS = 8
  211.         names = func.func_code.co_varnames
  212.         nrargs = func.func_code.co_argcount
  213.         if func.func_defaults:
  214.             nrdefaults = len(func.func_defaults)
  215.         else:
  216.             nrdefaults = 0
  217.         self.required = names[:nrargs-nrdefaults]
  218.         if func.func_defaults:
  219.             self.optional = tuple(map(None, names[nrargs-nrdefaults:nrargs],
  220.                                  func.func_defaults))
  221.         else:
  222.             self.optional = ()
  223.         varargs = []
  224.         ix = nrargs
  225.         if func.func_code.co_flags & CO_VARARGS:
  226.             self.varargs=names[ix]
  227.             ix = ix+1
  228.         if func.func_code.co_flags & CO_VARKEYWORDS:
  229.             self.kwargs=names[ix]
  230.  
  231.     view=HTMLFile('methodView', globals())
  232.  
  233.  
  234. def trim_doc_string(text):
  235.     """
  236.     Trims a doc string to make it format
  237.     correctly with structured text.
  238.     """
  239.     text=string.strip(text)
  240.     text=string.replace(text, '\r\n', '\n')
  241.     lines=string.split(text, '\n')
  242.     nlines=[lines[0]]
  243.     if len(lines) > 1:
  244.         min_indent=None
  245.         for line in lines[1:]:
  246.             indent=len(line) - len(string.lstrip(line))
  247.             if indent < min_indent or min_indent is None:
  248.                 min_indent=indent   
  249.         for line in lines[1:]:
  250.             nlines.append(line[min_indent:])
  251.     return string.join(nlines, '\n')
  252.     
  253.     
  254.     
  255.